package org.dromara.system.service.impl.pay;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.BusinessException;
import org.dromara.system.constant.MachineConstant;
import org.dromara.system.domain.WechatConfig;
import org.dromara.system.domain.base.JsApiOrderModel;
import org.dromara.system.domain.bo.InitPaySimOrderBo;
import org.dromara.system.domain.bo.RenewSimBo;
import org.dromara.system.domain.bo.SimMallOrderBo;
import org.dromara.system.service.IWechatConfigService;
import org.dromara.system.util.JsonUtil;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.InetAddress;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class WechatPay extends AbstractPayService {

    private final static String SIM_ORDER_NOTIFY_URL = "https://sim.hbtuding.com/system/mallOrder/callBak/wxPay";
    private final static String RE_NEW_NOTIFY_URL = "https://sim.hbtuding.com/system/renewRecords/renewSimWxCallBack";

    private final IWechatConfigService wechatConfigService;

    @Override
    public String initPaySimOrder(InitPaySimOrderBo bo) {
        log.info("initPaySimOrder={}", JSONUtil.toJsonStr(bo));
        BusinessException.isTrue(StrUtil.isBlank(bo.getOpenId()), "OPENID为空！");
        SimMallOrderBo simMallOrderBo = bo.getSimMallOrderBo();
        BigDecimal round = NumberUtil.round(NumberUtil.mul(simMallOrderBo.getAmount(), 100), 0, RoundingMode.HALF_UP);
        WechatConfig wechatConfig = wechatConfigService.getById(MachineConstant.NUMBER.ONE_L);
        try {
            Map<String, String> params = JsApiOrderModel
                .builder()
                .appid(wechatConfig.getAppId())
                .mch_id(wechatConfig.getMchId())
                .nonce_str("微信支付")
                .body("微信支付")
                .out_trade_no(simMallOrderBo.getOrderNo())
                // 支付金额注意是以分为单位的
                .total_fee(String.valueOf(round))
                .spbill_create_ip(InetAddress.getLocalHost().getHostAddress())
                .notify_url(SIM_ORDER_NOTIFY_URL)
                .trade_type(TradeType.JSAPI.getTradeType())
                .openid(bo.getOpenId())
                .attach(Convert.toStr(simMallOrderBo.getId()))
                .build()
                .createSign(wechatConfig.getMchKey(), SignType.MD5);
            String orderPay = JSONUtil.toJsonStr(params);
            String xmlResult = WxPayApi.pushOrder(false, JsonUtil.toMap(orderPay));
            log.info("initPaySimOrder=={}", xmlResult);
            Map<String, String> resultMap = WxPayKit.xmlToMap(xmlResult);
            if (StringUtils.equals(resultMap.get("return_code"), "SUCCESS")) {
                String prepayId = resultMap.get("prepay_id");
                Map<String, String> packageParams = WxPayKit.prepayIdCreateSign(prepayId, wechatConfig.getAppId(),
                    wechatConfig.getMchKey(), SignType.MD5);
                return JSONUtil.toJsonStr(packageParams);
            }
        } catch (Exception e) {
            BusinessException.isTrue(Boolean.TRUE, "微信拉起支付异常！");
        }
        return "";
    }

    @Override
    public String initPayReNewOrder(RenewSimBo bo) {
        log.info("initPayReNewOrder={}", JSONUtil.toJsonStr(bo));
        BusinessException.isTrue(StrUtil.isBlank(bo.getOpenId()), "OPENID为空！");
        BigDecimal round = NumberUtil.round(NumberUtil.mul(bo.getAmount(), 100), 0, RoundingMode.HALF_UP);
        WechatConfig wechatConfig = wechatConfigService.getById(MachineConstant.NUMBER.ONE_L);
        try {
            Map<String, String> params = JsApiOrderModel
                .builder()
                .appid(wechatConfig.getAppId())
                .mch_id(wechatConfig.getMchId())
                .nonce_str("微信支付")
                .body("微信支付")
                .out_trade_no(bo.getOrderNo())
                // 支付金额注意是以分为单位的
                .total_fee(String.valueOf(round))
                .spbill_create_ip(InetAddress.getLocalHost().getHostAddress())
                .notify_url(RE_NEW_NOTIFY_URL)
                .trade_type(TradeType.JSAPI.getTradeType())
                .openid(bo.getOpenId())
                .attach(bo.getOrderNo())
                .build()
                .createSign(wechatConfig.getMchKey(), SignType.MD5);
            String orderPay = JSONUtil.toJsonStr(params);
            String xmlResult = WxPayApi.pushOrder(false, JsonUtil.toMap(orderPay));
            log.info("initPayReNewOrder=={}", xmlResult);
            Map<String, String> resultMap = WxPayKit.xmlToMap(xmlResult);
            if (StringUtils.equals(resultMap.get("return_code"), "SUCCESS")) {
                String prepayId = resultMap.get("prepay_id");
                Map<String, String> packageParams = WxPayKit.prepayIdCreateSign(prepayId, wechatConfig.getAppId(),
                    wechatConfig.getMchKey(), SignType.MD5);
                return JSONUtil.toJsonStr(packageParams);
            }
        } catch (Exception e) {
            BusinessException.isTrue(Boolean.TRUE, "微信拉起支付异常！");
        }
        return "";
    }
}
